The Clean Architecture (Uncle Bob Blog 2012)
By separating the software into layers, and conforming to The Dependency Rule, you will create a system that is intrinsically testable, with all the benefits that implies.(Conclusion)
「ソフトウェアを層に分け、The Dependency Ruleに従うことで、本質的にテスト可能で、それが暗示する全ての恩恵を持ったシステムを作れるだろう」
データベースやWebフレームワークといった外側のパーツを置き換えられる
Though these architectures all vary somewhat in their details, they are very similar.
「どれも詳細は異なるが、類似している」
Hexagonal Architecture
Onion Architecture
Screaming Architecture
DCI
BCE
TODO リンクチェックしたい
They all have the same objective, which is the separation of concerns. They all achieve this separation by dividing the software into layers. Each has at least one layer for business rules, and another for interfaces.
separation of concerns = 関心の分離
ソフトウェアをレイヤ(層)に分けて実現
訳(メモ):ビジネスルールとインターフェースに関心を分離したい
各層は少なくとも1層を持つ(最低で合計2層)
これらのアーキテクチャが提供するシステムは
Independent of Frameworks
「フレームワークをツールとして使う」
Testable
「ビジネスルール自体をテストできる」
Independent of UI
例「Web UIをConsole UI (CUI) に置き換えられる」
Independent of Database
「ビジネスルール自体はデータベースと結びついていない」
Independent of any external agency
The diagram at the top of this article is an attempt at integrating all these architectures into a single actionable idea.
訳(メモ):これらのアーキテクチャを実用価値のある1つのアイデアに統合したのが、「あの図」
https://blog.cleancoder.com/uncle-bob/images/2012-08-13-the-clean-architecture/CleanArchitecture.jpg
The Dependency Rule
The outer circles are mechanisms. The inner circles are policies.
「外側は装置(※具体のことを言っている)。内側はpolicy(方針 ※抽象のことを言っている)」
4つの同心円の図で最も重要なルール
This rule says that source code dependencies can only point inwards.
「ソースコードの依存は内向きだけ」
(内向きでしかソースコードを利用できない。例えば、entityがexternal interfacesを使うのはNG)
「内側の円はどれも、外側の円にあるもののことを全く知らない」
関数やクラスや変数などの名前(name)について、内側の円では、外側の円にある名前を知らない
(図の要素を説明している)
内側の層を変えても外側には影響しない -> 関心の分離!
Entities
Enterprise wide business rules(図に黄色い文字で書いてある!)
最も一般的で高いレベルのルール
外部のなにかが変わったとしても最も変わりにくい
特定のアプリケーションに関する運用上の変更もentityレイヤには影響すべきでない
enterpriseでなく単一のアプリケーションなら、entityはアプリケーションのビジネスオブジェクト
👉 エンティティにて、アプリケーションがなくても存在すると言っていた覚え Use Cases
application specific business rules
(nrslibさん本より、アプリケーションはapply(問題解決=ソフトウェアを適用)している)
These use cases orchestrate the flow of data to and from the entities, and direct those entities to use their enterprise wide business rules to achieve the goals of the use case.
アプリケーションの運用の変更がUse Cases層とこのレイヤのソフトウェアに影響する
Interface Adapters
2種類の変換(adapt)
a set of adapters that convert data from the format most convenient for the use cases and entities, to the format most convenient for some external agency such as the Database or the Web
「データをユースケースやエンティティにとって最も便利な形式から外部にとって最も便利な形式へと変換する」(だからadapterという名前)
MVCアーキテクチャもこの層
If the database is a SQL database, then all the SQL should be restricted to this layer, and in particular to the parts of this layer that have to do with the database.
Also in this layer is any other adapter necessary to convert data from some external form, such as an external service, to the internal form used by the use cases and entities.
Frameworks and Drivers.
Generally you don’t write much code in this layer other than glue code that communicates to the next circle inwards.
This layer is where all the details go.
Only Four Circles?
No, the circles are schematic.
「4つだけではない。4つの円は概要を示したにすぎない」
However, The Dependency Rule always applies.
円の数よりも依存の方向のルール(内向きのみ)が重要、と言っている
The outermost circle is low level concrete detail. As you move inwards the software grows more abstract, and encapsulates higher level policies.
「外側は低レベルで具体的な詳細。内側は高レベルの方針」(で一般的、と続く)
Crossing boundaries.
4つの同心円の図の右下!
an example of how we cross the circle boundaries
flow of control(ピンク色)
It begins in the controller, moves through the use case, and then winds up executing in the presenter.
「コントローラから始まり、ユースケースを通って、プレゼンターで実行される」
source code dependencies
Each one of them points inwards towards the use cases.
「ユースケースに向かって内側に指し示す」
We usually resolve this apparent contradiction by using the Dependency Inversion Principle.
例:「ユースケースがプレゼンターを呼び出す」
直接呼び出すことはできない(The Dependency Ruleを侵害するため。ユースケースは外側の層のプレゼンターの名前を知らない)
So we have the use case call an interface (Shown here as Use Case Output Port) in the inner circle, and have the presenter in the outer circle implement it.
「ユースケースは、ユースケースと同じ層のインターフェースを呼び出す」
「外側の層のプレゼンターはこのインターフェースを実装する」
(これでThe Dependency Ruleを守りつつ、flow of controlを実現できた!)
(実行時はインターフェースを実装したプレゼンターインスタンスがユースケースに渡される。ユースケースは知っているインターフェースだけを使って目的を達成する)
We take advantage of dynamic polymorphism to create source code dependencies that oppose the flow of control
What data crosses the boundaries.
Typically the data that crosses the boundaries is simple data structures.
Data Transfer object
(ファウラー?)
関数呼び出しの引数
hashmapに詰める
など
The important thing is that isolated, simple, data structures are passed across the boundaries.
We don’t want to cheat and pass Entities or Database rows.
The Dependency Ruleを侵害している
データベースフレームワークが返すRowStructureもそのまま内側の層に渡してはならない(内側の層が外側を知っていることになる)
So when we pass data across a boundary, it is always in the form that is most convenient for the inner circle.
「境界を横切ってデータを渡すとき、データは常に内側のサークルにとって最も便利な形式となる」
(IMO:ユースケースからはエンティティを作ってエンティティに渡すのが便利ということかも。interface adaptersからはプリミティブなデータ型でユースケースに渡すのが便利ということかも)
なるセミで図の読み方を解説していたじゃん!